//created by noellynch
//Nov 12, 2008

package com.sceneworker.editors.glslshadereditor;

import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.logging.Level;

import org.lwjgl.opengl.ARBFragmentShader;
import org.lwjgl.opengl.ARBShaderObjects;
import org.lwjgl.opengl.ARBVertexShader;
import org.lwjgl.opengl.GL20;

import com.jme.system.JmeException;
import com.jme.util.geom.BufferUtils;

public class LWJGLShaderGLSLCompiler {
	/** OpenGL id for this program. * */
	private int programID = -1;

	/** OpenGL id for the attached vertex shader. */
	private int shaderID = -1;


	public	LWJGLShaderGLSLCompiler() {

	}

	public	int	getShaderID() {
		return shaderID;
	}

	/**
	 * Loads a string into a ByteBuffer
	 *
	 * @param data string to load into ByteBuffer
	 * @return the converted string
	 */
	private ByteBuffer load(String data) {
		try {
			byte[] bytes = data.getBytes();
			ByteBuffer program = BufferUtils.createByteBuffer(bytes.length);
			program.put(bytes);
			program.rewind();
			return program;
		} catch (Exception e) {

			return null;
		}
	}

	public	String	compileShader(String str_shader, int i_shaderType) {
		ByteBuffer lcl_buffer = str_shader != null ? load(str_shader) : null;
		return compile(lcl_buffer, i_shaderType);
	}
	
	protected String compile(ByteBuffer cl_buffer, int i_shaderType) {

		if (cl_buffer == null) {
			return "Buffer is null. The shader may not of been loaded correctly.";
		}

		String		lstr_compileResult = null;

		if (cl_buffer != null) {
			shaderID = ARBShaderObjects.glCreateShaderObjectARB(i_shaderType);
			
			// Create the sources
			ARBShaderObjects.glShaderSourceARB(shaderID, cl_buffer);

			// Compile the vertex shader
			IntBuffer compiled = BufferUtils.createIntBuffer(1);
			ARBShaderObjects.glCompileShaderARB(shaderID);
			ARBShaderObjects.glGetObjectParameterARB(shaderID,
					ARBShaderObjects.GL_OBJECT_COMPILE_STATUS_ARB, compiled);
			lstr_compileResult = checkProgramError(compiled, shaderID);
			
			ARBShaderObjects.glDeleteObjectARB(shaderID);

		}

		return lstr_compileResult;
	}

	/**
	 * Check for program errors. If an error is detected, program exits.
	 *
	 * @param compiled the compiler state for a given shader
	 * @param id shader's id
	 */
	private String checkProgramError(IntBuffer compiled, int id) {
		if (compiled.get(0) == 0) {
			IntBuffer iVal = BufferUtils.createIntBuffer(1);
			ARBShaderObjects.glGetObjectParameterARB(id,
					ARBShaderObjects.GL_OBJECT_INFO_LOG_LENGTH_ARB, iVal);
			int length = iVal.get();
			String out = null;

			if (length > 0) {
				ByteBuffer infoLog = BufferUtils.createByteBuffer(length);

				iVal.flip();
				ARBShaderObjects.glGetInfoLogARB(id, iVal, infoLog);

				byte[] infoBytes = new byte[length];
				infoLog.get(infoBytes);
				out = new String(infoBytes);
			}

			return out;

		}

		return null;
	}

}
